package com.alipay.rebate.shop.scheduler.productimport;

import com.alipay.rebate.shop.dao.mapper.ProductMapper;
import com.alipay.rebate.shop.helper.InterfaceStatisticsHelper;
import com.alipay.rebate.shop.model.Product;
import com.alipay.rebate.shop.pojo.dataoke.DataokeProduct;
import com.alipay.rebate.shop.pojo.dataoke.DataokeProductListData;
import com.alipay.rebate.shop.pojo.dataoke.DataokeProductListRsp;
import com.alipay.rebate.shop.pojo.haodanku.HaodankuProduct;
import com.alipay.rebate.shop.pojo.haodanku.HaodankuProductListRsp;
import com.alipay.rebate.shop.utils.DataokeUtil;
import com.alipay.rebate.shop.utils.HaodankuUtil;
import com.alipay.rebate.shop.utils.ListUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ProductImporter {

  private final Logger logger = LoggerFactory.getLogger(ProductImporter.class);

  @Autowired
  ProductMapper productMapper;

  @Autowired
  InterfaceStatisticsHelper interfaceStatisticsHelper;

  // 拉取全部商品
  public synchronized void importAllProduct() {
    // import dataoke product
    importAllDataokeProduct();
    importAllHaodankuProduct();
  }

  private void importAllDataokeProduct(){

    List<Long> goodsIdsInserted = getDataokeGoodIdsInserted();
    logger.trace("goodsIdsInserted is: {}",goodsIdsInserted);

    String pageId = "1";
    logger.debug("----------importAllDataokeProduct----------");
    logger.debug("initial pageId is : {}",pageId);

    while(pageId != null && !pageId.equals("0")){
      DataokeProductListRsp rsp = DataokeUtil.getAllProducts(pageId);
      DataokeProductListData data = rsp.getData();
      if(data == null){
        break;
      }
      pageId = data.getPageId();
      logger.debug("all next pageId is : {}",pageId);
      List<Product> products = getProductFromDataokeProductListRsp(rsp);
      pageId = setPageIdToNullIfListEmpty(products,pageId);
      products = fileterProductInsertIndbBefore(products,goodsIdsInserted);
      logger.debug("filter product insert before : {}",products);
      if(!ListUtil.isEmptyList(products)){
        productMapper.insertProducts(products);
        List<Long> newGoodsIdList =
        products.stream().map(product -> product.getGoodsId()).collect(Collectors.toList());
        goodsIdsInserted.addAll(newGoodsIdList);
      }
    }

  }

  private void importAllHaodankuProduct(){

    List<Long> goodsIdsInserted = getHaodankuGoodIdsInserted();
    logger.trace("goodsIdsInserted is: {}",goodsIdsInserted);

    String pageId = "1";
    logger.debug("----------importAllHaodankuProduct----------");
    logger.debug("initial pageId is : {}",pageId);

    while(pageId != null && !pageId.equals("0") && !pageId.equals("null")){
      HaodankuProductListRsp rsp = HaodankuUtil.getAllProducts(pageId);
      if(rsp == null) break;
      pageId = String.valueOf(rsp.getMin_id());
      logger.debug("next pageId is : {}",pageId);
      List<Product> products = getProductFromHaodankuProductListRsp(rsp);
      products = fileterProductInsertIndbBefore(products,goodsIdsInserted);
      logger.debug("filter product insert before : {}",products);
      if(!ListUtil.isEmptyList(products)){
        productMapper.insertProducts(products);
        List<Long> newGoodsIdList =
            products.stream().map(product -> product.getGoodsId()).collect(Collectors.toList());
        goodsIdsInserted.addAll(newGoodsIdList);
      }
    }
  }

  public void importAllDataokeGoodsFriendsCircle(){

    try {
      String pageId = "1";
      logger.debug("----------importAllDataokeProduct----------");
      logger.debug("initial pageId is : {}", pageId);
      while (pageId != null && !pageId.equals("0")) {
        DataokeProductListRsp rsp = DataokeUtil.getFriendsCircleListReqTwo(pageId);
        DataokeProductListData data = rsp.getData();
        if (data == null) {
          break;
        }
        pageId = data.getPageId();
        logger.debug("all next pageId is : {}", pageId);
        List<Product> products = getProductFromDataokeProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products, pageId);
        logger.debug("filter product insert before : {}", products);
        if (!ListUtil.isEmptyList(products)) {
          productMapper.insertProducts(products);
        }
      }
    }catch (Exception ex){
      logger.error("import exception",ex);
      logger.error("允许因网络等原因失败,进行下一次重新请求");
    }
  }

  // 定时拉取新商品
  public synchronized void pullProduct(
      String startTime,String endTime,
      String startHour, String endHour
  ) {

    pullDataokeProduct(startTime,endTime);
    pullHaodankuProduct(startHour,endHour);

  }

  private void pullDataokeProduct(String startTime,String endTime){

    List<Long> goodsIdsInserted = getDataokeGoodIdsInserted();
    logger.trace("goodsIdsInserted is: {}",goodsIdsInserted);

    String pageId = "1";
    logger.debug("----------pullDataokeProduct----------");
    logger.debug("initial pageId is : {}",pageId);

    while(pageId != null && !pageId.equals("0")){
      try {

        interfaceStatisticsHelper.getCount("pullProductsByTime");
        DataokeProductListRsp rsp = DataokeUtil.pullProductsByTime(pageId,startTime,endTime);

        DataokeProductListData data = rsp.getData();
        if(data == null){
          break;
        }
        pageId = data.getPageId();
        logger.debug("pull next pageId is : {}",pageId);
        List<Product> products = getProductFromDataokeProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products,pageId);
        products = fileterProductInsertIndbBefore(products,goodsIdsInserted);
//        logger.debug("filter dataoke product insert before : {}",products);
        if(!ListUtil.isEmptyList(products)){
          logger.debug("dataoke pull new product size is: {}", products.size());
          productMapper.insertProducts(products);
          List<Long> newGoodsIdList =
              products.stream().map(product -> product.getGoodsId()).collect(Collectors.toList());
          goodsIdsInserted.addAll(newGoodsIdList);
        }
      }catch (Exception ex){
        logger.error("import exception",ex);
        logger.error("允许因网络等原因失败,进行下一次重新请求");
      }
    }
  }

  private void pullHaodankuProduct(String startTime, String endTime){

    List<Long> goodsIdsInserted = getHaodankuGoodIdsInserted();
    logger.trace("goodsIdsInserted is: {}",goodsIdsInserted);

    String pageId = "1";
    logger.debug("----------pullHaodankuProduct----------");
    logger.debug("initial pageId is : {}",pageId);

    while(pageId != null && !pageId.equals("0") && !pageId.equals("null")){
      try {
        HaodankuProductListRsp rsp = HaodankuUtil.pullProductsByTime(pageId,startTime,endTime);
        if(rsp == null) break;
        pageId = String.valueOf(rsp.getMin_id());
        logger.debug("next pageId is : {}",pageId);
        List<Product> products = getProductFromHaodankuProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products,pageId);
        products = fileterProductInsertIndbBefore(products,goodsIdsInserted);
//        logger.debug("filter haodanku product insert before : {}",products);
        if(!ListUtil.isEmptyList(products)){
          logger.debug("haodanku pull new product size is: {}", products.size());
          productMapper.insertProducts(products);
          List<Long> newGoodsIdList =
              products.stream().map(product -> product.getGoodsId()).collect(Collectors.toList());
          goodsIdsInserted.addAll(newGoodsIdList);
        }
      }catch (Exception ex){
        logger.error("import exception",ex);
      }
    }
  }

  // 更新商品
  public void getNewestProduct() {
    getNewestDataokeProduct();
    getNewestHaodankuProduct();
  }

  private void getNewestDataokeProduct(){
    String pageId = "1";
    logger.debug("----------getNewestDataokeProduct----------");
    logger.debug("initial pageId is : {}",pageId);
    while(pageId != null && !pageId.equals("0")){
      try {
        interfaceStatisticsHelper.getCount("getNewestProduct");
        DataokeProductListRsp rsp = DataokeUtil.getNewestProducts(pageId);
        DataokeProductListData data = rsp.getData();
        if(data == null){
          break;
        }
        pageId = data.getPageId();
        logger.debug("newest next pageId is : {}",pageId);
        List<Product> products = getProductFromDataokeProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products,pageId);
        if(!ListUtil.isEmptyList(products)){
          productMapper.updateBatch(products);
        }
      }catch (Exception ex){
        logger.error("import exception",ex);
      }
    }
  }

  private void getNewestHaodankuProduct(){
    String pageId = "1";
    logger.debug("----------getNewestHaodankuProduct----------");
    logger.debug("initial pageId is : {}",pageId);
    while(pageId != null && !pageId.equals("0") && !pageId.equals("null")){
      try {
        HaodankuProductListRsp rsp = HaodankuUtil.getNewestProducts(pageId);
        if(rsp == null) break;
        pageId = String.valueOf(rsp.getMin_id());
        List<Product> products = getProductFromHaodankuProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products,pageId);
        if(!ListUtil.isEmptyList(products)){
          productMapper.updateBatch(products);
        }
      }catch (Exception ex){
        logger.error("import exception",ex);
      }
    }
  }

  // 失效商品
  public synchronized void getStaleProduct(
      String startTime,String endTime,
      String startHour, String endHour
  ) {
    getStaleDataokeProduct(startTime,endTime);
    getStaleHaodankuProduct(startHour,endHour);
  }

  private void getStaleDataokeProduct(String startTime,String endTime){
    String pageId = "1";
    logger.debug("----------getStaleDataokeProduct----------");
    logger.debug("initial pageId is : {}",pageId);
    while(pageId != null && !pageId.equals("0")){
      try {
        interfaceStatisticsHelper.getCount("getStaleProductsByTime");
        DataokeProductListRsp rsp = DataokeUtil.getStaleProductsByTime(pageId,startTime,endTime);
        DataokeProductListData data = rsp.getData();
        if(data == null){
          break;
        }
        pageId = data.getPageId();
        logger.debug("stale next pageId is : {}",pageId);
        List<Product> products = getProductFromDataokeProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products,pageId);
        if(!ListUtil.isEmptyList(products)){
          logger.debug("dataoke stale product size is: {}", products.size());
          productMapper.deleteProductsById(products);
        }
      }catch (Exception ex){
        logger.error("import exception",ex);
      }
    }
  }

  private void getStaleHaodankuProduct(String startHour, String endHour){
    String pageId = "1";
    logger.debug("----------getStaleHaodankuProduct----------");
    logger.debug("initial pageId is : {}",pageId);
    while(pageId != null && !pageId.equals("0") && !pageId.equals("null")){
      try {
        HaodankuProductListRsp rsp = HaodankuUtil.getStaleProductsByTime(pageId,startHour,endHour);
        if(rsp == null) break;
        pageId = String.valueOf(rsp.getMin_id());
        logger.debug("stale pageId is : {}",pageId);
        List<Product> products = getProductFromHaodankuProductListRsp(rsp);
        pageId = setPageIdToNullIfListEmpty(products,pageId);
        if(!ListUtil.isEmptyList(products)){
          logger.debug("haodanku stale product size is: {}", products.size());
          productMapper.deleteProductsById(products);
        }
      }catch (Exception ex){
        logger.error("import exception",ex);
      }
    }
  }

  private List<Product> getProductFromDataokeProductListRsp(DataokeProductListRsp rsp){
    List<DataokeProduct> productList = rsp.getData().getList();
    List<Product> products = new ArrayList<>();
    if(productList != null){
      productList.forEach(dataokeProduct -> {
        products.add(DataokeUtil.convert2Product(dataokeProduct));
      });
    }
    return products;
  }

  private List<Product> getProductFromHaodankuProductListRsp(HaodankuProductListRsp rsp){
    List<HaodankuProduct> productList = rsp.getData();
    if(productList != null){
      List<Product> products = new ArrayList<>();
      productList.forEach(haodankuProduct -> {
        products.add(HaodankuUtil.convert2Product(haodankuProduct));
      });
      return products;
    }
    return null;
  }

  /**
   * （TODO）
   * 可以考虑做缓存
   * 暂时不做,测试可能耗费一定时间,并且调用次数少
   * @return
   */
  private List<Long> getDataokeGoodIdsInserted(){
    List<Long> goodsIdsInserted = productMapper.selectDataokeGoodsIdsIndb();
    if(goodsIdsInserted == null) goodsIdsInserted = new ArrayList<>();
    return goodsIdsInserted;
  }

  /**
   * （TODO）
   * 可以考虑做缓存
   * 暂时不做,测试可能耗费一定时间,并且调用次数少
   * @return
   */
  private List<Long> getHaodankuGoodIdsInserted(){
    List<Long> goodsIdsInserted = productMapper.selectHaodankuGoodsIdsIndb();
    if(goodsIdsInserted == null) goodsIdsInserted = new ArrayList<>();
    return goodsIdsInserted;
  }

//  private List<Long> getDataokeFriendsCircleList(){
//    List<Long> goodsIdsInserted = productMapper.selectDataokeGoodsFriendsCircleList();
//    if(goodsIdsInserted == null) goodsIdsInserted = new ArrayList<>();
//    return goodsIdsInserted;
//  }

  private List<Product> fileterProductInsertIndbBefore(List<Product> products,List<Long> goodsIdsInserted){
    if(products == null) products = new ArrayList<>();
    return products.stream().filter(
        product ->{
          Long goodsId = product.getGoodsId();
          return  ! goodsIdsInserted.contains(goodsId);
        }

    ).collect(Collectors.toList());
  }


  private String setPageIdToNullIfListEmpty(List<Product> products, String pageId){

    if(ListUtil.isEmptyList(products)){
      pageId = null;
    }
    // 从第二次开始，如果返回的pageId 是 1 , 那么就直接停止
    if("1".equals(pageId)){
      return null;
    }
    return pageId;
  }
}
